
import { createRenderer } from "vue"
import { hyphenate } from '@vue/shared'

import { CanvasWindow } from "./IWindow.js";
import { IElement } from "./IElement.js";
import { CreateCustomElement } from "./CustomElement.js";

import IconFontTTF from "./font/iconfont.ttf";
// console.log('Font URL:', IconFontTTF);

class TextNode {
    constructor(text) {
        this.m_text = text;
        this.m_parent = null;
    }

    SetParent(parent) { this.m_parent = parent; }
    GetParent() { return this.m_parent; }
}

class IComment extends IElement {
    constructor(text) {
        super();
        this.m_text = text;
        this.SetTagName("Comment");
    }
}

class VueGuiWindow extends CanvasWindow {
    constructor(canvas, input, vue_app_creator) {
        super(canvas, input);

        this.LoadFont("iconfont", IconFontTTF).then(() => {
            const { createApp } = createRenderer(this.GetVueRendererOptions()); // 创建自定义App
            this.m_vue_app = vue_app_creator(createApp);
            this.m_vue_app.config.compilerOptions.isCustomElement = (tag) => true; // 所有元素均为定制元素
            this.m_vue_app.mount(this.GetRoot());
        });
    }

    GetVueRendererOptions() {
        const root = this.GetRoot();

        return {
            patchProp: (el, key, prevValue, nextValue, namespace, parentComponent) => {
                if (key === 'style') {
                    if (nextValue) {
                        if (typeof nextValue === 'string') {
                            el.InsertAttribute(key, nextValue);
                        } else {
                            let cssString = '';
                            for (const key in nextValue) {
                                cssString = cssString + hyphenate(key) + ":" + nextValue[key] + ";";
                            }
                            el.InsertAttribute(key, cssString);
                        }
                    } else {
                        el.DeleteAttribute(key);
                    }
                } else if (key.charCodeAt(0) === 111 /* o */ && key.charCodeAt(1) === 110 /* n */ && (key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97) /* uppercase letter */) {
                    // v-model 指令实现
                    // 1. el.value = v-model 绑定的变量
                    // 2. 监听 onUpdate:modelValue 事件获取更新后的值赋值给 v-model绑定变量 el.addEventListener("onUpdate:modelValue", (event) => { nextValue(event.GetValue()); });
                    if (key.startsWith('onUpdate:')) {
                        // console.log("onUpdate:", key, nextValue);
                        el.AddEventListener("change", (event) => { nextValue(event.GetValue()); });
                        return;
                    } 
                    if (nextValue) {
                        el.AddEventListener(key.slice(2).toLowerCase(), nextValue);
                    } else {
                        el.RemoveEventListener(key.slice(2).toLowerCase(), prevValue);
                    }
                } else {
                    // console.log("attr", key, nextValue);
                    el.InsertAttribute(key, nextValue);
                }
            },

            insert: (child, parent, anchor) => {
                if (child instanceof TextNode) {
                    parent.SetText(child.text);
                    child.SetParent(parent);
                } else {
                    parent.InsertChildren(child, anchor || null);
                }
            },

            remove: child => {
                const parent = child.GetParent()
                if (parent) {
                    parent.DeleteChildren(child)
                }
            },

            createElement: (tag, namespace, is, props) => {
                tag = tag.toLowerCase()

                let el = CreateCustomElement(tag);
                if (!el) {
                    el = new IElement();
                }
                el.SetTagName(tag);
                el.SetWindow(this);
                el.SetRoot(root);
                el.addEventListener = () => {};
                el.removeEventListener = () => {};
                // console.log(tag, props);
                return el;
            },

            createText: text => {
                return new TextNode(text);
            },

            createComment: text => {
                const comment = new IComment(text);
                comment.SetWindow(this);
                comment.SetRoot(root);
                return comment;
            },

            setText: (node, text) => {
                node.SetText(text);
            },

            setElementText: (el, text) => {
                el.SetText(text);
            },

            parentNode: node => {
                return node ? node.GetParent() : null;
            },

            nextSibling: node => {
                const parent = node.GetParent();
                const childrens = parent.GetChildrens();
                const childrens_size = childrens.length - 1;
                for (let i = 0; i < childrens_size; i++) {
                    if (childrens[i] == node) {
                        return childrens[i + 1];
                    }
                }
            },
        }
    }
}

export { VueGuiWindow }